// 库文件
#include <stdio.h>
#include <stdint.h>
#include <stdbool.h>
#include <stdlib.h>
#include "FreeRTOS.h"
#include "task.h"
#include "cmsis_os2.h"
// HAL库文件
#include "main.h"
// 自定义文件
#include "lightLedTask.h"

extern osEventFlagsId_t lightSensorEvent; // 外部事件标志
extern TIM_HandleTypeDef htim2;           // 外部定时器
extern ADC_HandleTypeDef hadc1;           // 外部ADC

/* 接口函数 */

/* EXTI中断函数：统一定义在sys.c文件中 */

/**
 * @brief  获取ADC的数值
 * @param  无
 * @return 返回ADC的原始值（0-4095）
 **/
static uint16_t LightLedADCRead(void)
{
    HAL_ADC_Start(&hadc1); // 开启ADC，开启常规组转换

    // 等待常规组转换完成(延时100ms)
    if (HAL_ADC_PollForConversion(&hadc1, 100) == HAL_OK)
        return HAL_ADC_GetValue(&hadc1);

    return 0;
}

/**
 * @brief  处理一定数量的ADC的数值
 * @param  无
 * @return 返回ADC的处理后的平均值
 **/
static uint16_t LightLedGetData(void)
{
    uint16_t tempData = 0;

    // 读取一定数量的数值
    for (uint8_t i = 0; i < LIGHT_LED_READ_TIMES; i++)
    {
        tempData += LightLedADCRead();
    }
    tempData /= LIGHT_LED_READ_TIMES; // 取平均值

    return tempData;
}

/**
 * @brief ADC值等值转换成CCR值
 * @param {*}
 * @return ADC值:0 - 1000
 */
static uint16_t ADCChangeCCR(void)
{
    return (LightLedGetData() * (htim2.Init.Period + 1)) / 4096;
}

/* 任务函数 */
static void LightLedTask(void *argument)
{
    (void)argument;

    uint32_t flags;
    GPIO_PinState readPin;
    bool isLedOn = false;
    uint16_t lastDutyValue = 0;

    HAL_TIM_PWM_Start(&htim2, TIM_CHANNEL_3);

    while (1)
    {
        // 非阻塞等待事件（10ms超时）
        flags = osEventFlagsWait(lightSensorEvent, 0x0001, osFlagsWaitAny, 10);

        if (flags & 0x0001)
        {
            osDelay(10); // 按键消抖

            // 等待按键释放
            do
            {
                osDelay(5);
                readPin = HAL_GPIO_ReadPin(LIGHT_BTN_GPIO_Port, LIGHT_BTN_Pin);
            } while (readPin == GPIO_PIN_RESET);

            osDelay(10); // 释放消抖

            isLedOn = !isLedOn; // 切换状态
            osEventFlagsClear(lightSensorEvent, 0x0001);

            // LED刚关闭时立即设置占空比为0
            if (!isLedOn)
            {
                __HAL_TIM_SET_COMPARE(&htim2, TIM_CHANNEL_3, 0);
                printf("[LightLedTask] LED turned off.\r\n");
            }
        }

        // LED开启时持续更新亮度
        if (isLedOn)
        {
            uint16_t newDutyValue = ADCChangeCCR();

            if (abs(newDutyValue - lastDutyValue) > 5)
            {
                __HAL_TIM_SET_COMPARE(&htim2, TIM_CHANNEL_3, newDutyValue);
                // printf("[LightLedTask] Duty cycle updated to %d.\r\n", newDutyValue);
                lastDutyValue = newDutyValue;
            }
        }

        osDelay(10); // 控制循环频率
    }
}

/* 入口函数 */
void LightLedTaskEnter(void)
{
    // 任务属性
    osThreadAttr_t attr = {
        .name = "LightLedTask",
        .stack_size = 2048,
        .priority = (osPriority_t)osPriorityNormal};

    // 创建事件标志：统一定义在sys.c文件中

    // 创建任务
    if (osThreadNew((osThreadFunc_t)LightLedTask, (void *)NULL, &attr) == NULL)
    {
        printf("[LightLedTaskEnter] Failed to create to light led task!\r\n");
        osEventFlagsDelete(lightSensorEvent);
    }
}
